
#include <ttg/libs.h>
#include "Common/BodyManager.h"
#include "Common/Visualizer.h"
#include "Serial/Simulation.h"
#include "TBB/Simulation.h"
#include "PureCUDA/Simulation.h"
#include "ttgLib_Simple/Simulation.h"
#include "ttgLib_Advanced/Simulation.h"

#include <ttg/pipeline.h>

using namespace ttg::pipeline;

int main()
{
	//Initing.
	ttg::services::ServiceBase::getRef()->start();
	printf("TTG plus CUDA: NBody\n");
	printf("CPU type: %s\n\n", ttg::services::CPUAnalyzer::getRef()->getCPUInfo());
	ttg::utils::UtilManager::getRef()->addUtility("ParameterManager");
	//BodyManager bodies(4 * 1024);
	BodyManager bodies(512);
	//Creating parameters, cores and visualizer.
	Pipeline<SeparatedBodies::SubVector, SeparatedBodies::SubVector> visualizer(
		wrap(new Visualizer<SeparatedBodies::SubVector>(1.0f)), "Visualizer");
	ParameterEnum core("Calculation core", "Serial|Intel TBB|NVidia CUDA|ttgLib (simple)|ttgLib (advanced)");
	ICalculationCore *core_refs[] = { new serialCore(),
									  new tbbCore(),
									  new cudaCore(),
									  new ttgCore_Simple(),
									  new ttgCore_Advanced() };
	//Simulating.
	while (true)
	{
		double time;
		visualizer.run(bodies.getSeparatedBodies());
		time = core_refs[core]->simulate(bodies.getInterleavedBodies(), DTIME);
		printf("Elapsed time: %lf\n", time);
	}
	return 0;
}
